// C3P0 Movable Figure
// Anthony Dietrich 10/19-25/2012


#include <windows.h>
#include <GL/glut.h>

// Define all sizes for body part objects.
// Can turn these into called variables if need be.
#define HEAD_LENGTH		1.5
#define HEAD_RADIUS		1.15

#define OUTER_EYE		.35
#define INNER_EYE		.1
#define MOUTH_SIZE		.15

#define TORSO_LENGTH	5.0
#define TORSO_RADIUS	1.0
#define TORSO_WIDTH		1.75

#define BICEP_LENGTH	2.0
#define BICEP_RADIUS	0.6

#define ARM_LENGTH		2.5
#define ARM_RADIUS		0.5

#define THIGH_LENGTH	3.25
#define THIGH_RADIUS	0.75

#define SHIN_LENGTH		3.0
#define SHIN_RADIUS		0.65

#define HAND_LENGTH		1.5
#define HAND_RADIUS		0.25
#define HAND_WIDTH		3.0

#define FOOT_LENGTH		2.25
#define FOOT_RADIUS		0.25
#define FOOT_WIDTH		3.0

#define SCREEN_WIDTH	500
#define SCREEN_HEIGHT	500

// Setup all initial joint angles: torso: rotate, pitch, side to side; head: pitch, rotate, side to side;	
// leftShoulder: pitch, rotate, flap; leftElbow, leftWrist, rightShoulder: pitch, rotate, flap; 
// rightElbow, rightWrist, leftHip: pitch, flap; leftKnee, leftAnkle, rightHip: pitch, flap; rightKnee, rightAnkle  
static GLfloat theta[24] = {15.0, 0.0, 0.0, 0.0, 0.0, 0.0, 190.0, -25.0, 25.0, -90.0, 0.0, 
	190.0, 25.0, -25.0, -90.0, 0.0, 170.0, 0.0, 15.0, 250.0, 200.0, 0.0, 10.0, 260.0};

//angle for movement manipulation
static GLint angle;
static GLint selectstate;
HWND hWnd;


//quadric objects - I named these after the joints they move (sort of...)
GLUquadricObj	*rTorso, *rHead, *eyes, *upArmCaps, *lowArmCaps, *leftShoulder, *leftElbow, *leftWrist, 
	*rightShoulder,	*rightElbow, *rightWrist, *wristCaps, *leftHip, *leftKnee, *leftAnkle,
	*rightHip, *rightKnee, *rightAnkle, *upLegCaps, *lowLegCaps, *feetCaps, *tCaps;

//each method creates a body part
void torso()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	glScalef(TORSO_WIDTH, 1.0, 1.0);
	gluDisk(tCaps, 0.0, TORSO_RADIUS, 10, 10);
	gluCylinder(rTorso, TORSO_RADIUS, TORSO_RADIUS, TORSO_LENGTH, 10, 10);
	glTranslatef(0.0, 0.0, TORSO_LENGTH);
	gluDisk(tCaps, 0.0, TORSO_RADIUS, 10, 10);
	glPopMatrix();
}

void head()
{
	glPushMatrix();	 
	glRotatef(-90.0, 0.0, 1.0, 0.0);
	glTranslatef(0.0, 0.35*HEAD_LENGTH,0.0);
	glScalef(HEAD_RADIUS, HEAD_LENGTH, HEAD_RADIUS);
	gluSphere(rHead, 1.0, 15, 15);

	glScalef(1/HEAD_RADIUS, 1/HEAD_LENGTH, 1/HEAD_RADIUS);
	glTranslatef(HEAD_RADIUS, .25*HEAD_LENGTH, OUTER_EYE+INNER_EYE);
	glRotatef(90.0, 0.0, 1.0, 0.0);
	glRotatef(-16.0, 1.0, 0.0, 0.0);

	gluDisk(eyes, INNER_EYE, OUTER_EYE, 10, 10 );  //eye
	glColor3f(1.0, 0.0, 0.0);
	gluSphere(eyes, INNER_EYE, 10, 10);	//eyeball
	glColor3f(0.858824, 0.858824, 0.439216);
	glRotatef(180.0, 0.0, 1.0, 0.0);
	gluCylinder(eyes, OUTER_EYE, OUTER_EYE, .5*HEAD_RADIUS, 10, 10);	 //socket
	glRotatef(180.0, 0.0, 1.0, 0.0);
	glTranslatef(2*OUTER_EYE,0.0,0.0);
	gluDisk(eyes, INNER_EYE, OUTER_EYE, 10, 10 );   //eye
	glColor3f(1.0, 0.0, 0.0);
	gluSphere(eyes, INNER_EYE, 10, 10);	//eyeball
	glColor3f(0.858824, 0.858824, 0.439216);
	glRotatef(180.0, 0.0, 1.0, 0.0);
	gluCylinder(eyes, OUTER_EYE, OUTER_EYE, .5*HEAD_RADIUS, 10, 10);	 //socket
	glPopMatrix();
}

void leftBicep()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	gluCylinder(leftShoulder, BICEP_RADIUS, BICEP_RADIUS, BICEP_LENGTH, 10, 10);
	glRotatef(180.0, 1.0, 0.0, 0.0);
	gluDisk(upArmCaps, 0.0, BICEP_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, -BICEP_LENGTH);
	gluDisk(upArmCaps, 0.0, BICEP_RADIUS, 10, 10);
	glPopMatrix();
}

void leftForearm()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	gluCylinder(leftElbow, ARM_RADIUS, ARM_RADIUS, ARM_LENGTH, 10, 10);
	gluDisk(lowArmCaps, 0.0, ARM_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, ARM_LENGTH);
	gluDisk(lowArmCaps, 0.0, ARM_RADIUS, 10, 10);
	glPopMatrix();
}

void leftHand()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	glScalef(HAND_WIDTH, 1.0, 1.0);
	gluCylinder(leftWrist, HAND_RADIUS, HAND_RADIUS, HAND_LENGTH, 10, 10);
	gluDisk(wristCaps, 0.0, HAND_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, HAND_LENGTH);
	gluDisk(wristCaps, 0.0, HAND_RADIUS, 10, 10);
	glPopMatrix();
}

void rightBicep()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	gluCylinder(rightShoulder, BICEP_RADIUS, BICEP_RADIUS, BICEP_LENGTH, 10, 10);
	glRotatef(180.0, 1.0, 0.0, 0.0);
	gluDisk(upArmCaps, 0.0, BICEP_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, -BICEP_LENGTH);
	gluDisk(upArmCaps, 0.0, BICEP_RADIUS, 10, 10);
	glPopMatrix();
}

void rightForearm()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	gluCylinder(rightElbow, ARM_RADIUS, ARM_RADIUS, ARM_LENGTH, 10, 10);
	gluDisk(lowArmCaps, 0.0, ARM_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, ARM_LENGTH);
	gluDisk(lowArmCaps, 0.0, ARM_RADIUS, 10, 10);
	glPopMatrix();
}

void rightHand()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	glScalef(HAND_WIDTH, 1.0, 1.0);
	gluCylinder(rightWrist, HAND_RADIUS, HAND_RADIUS, HAND_LENGTH, 10, 10);
	gluDisk(wristCaps, 0.0, HAND_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, HAND_LENGTH);
	gluDisk(wristCaps, 0.0, HAND_RADIUS, 10, 10);
	glPopMatrix();
}

void leftThigh()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	gluCylinder(leftHip, THIGH_RADIUS, THIGH_RADIUS, THIGH_LENGTH,10,10);
	gluDisk(upLegCaps, 0.0, THIGH_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, THIGH_LENGTH);
	gluDisk(upLegCaps, 0.0, THIGH_RADIUS, 10, 10);
	glPopMatrix();
}

void leftShin()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	gluCylinder(leftKnee, SHIN_RADIUS, SHIN_RADIUS, SHIN_LENGTH,10,10);
	gluDisk(lowLegCaps, 0.0, SHIN_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, SHIN_LENGTH);
	gluDisk(lowLegCaps, 0.0, SHIN_RADIUS, 10, 10);
	glPopMatrix();
}

void leftFoot()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	glScalef(FOOT_WIDTH, 1.0, 1.0);
	gluCylinder(leftAnkle, FOOT_RADIUS, FOOT_RADIUS, FOOT_LENGTH, 10, 10);
	gluDisk(feetCaps, 0.0, FOOT_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, FOOT_LENGTH);
	gluDisk(feetCaps, 0.0, FOOT_RADIUS, 10, 10);
	glPopMatrix();
}

void rightThigh()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	gluCylinder(rightHip, THIGH_RADIUS, THIGH_RADIUS, THIGH_LENGTH,10,10);
	gluDisk(upLegCaps, 0.0, THIGH_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, THIGH_LENGTH);
	gluDisk(upLegCaps, 0.0, THIGH_RADIUS, 10, 10);
	glPopMatrix();
}

void rightShin()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	gluCylinder(rightKnee, SHIN_RADIUS, SHIN_RADIUS, SHIN_LENGTH,10,10);
	gluDisk(lowLegCaps, 0.0, SHIN_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, SHIN_LENGTH);
	gluDisk(lowLegCaps, 0.0, SHIN_RADIUS, 10, 10);
	glPopMatrix();
}

void rightFoot()
{
	glPushMatrix();
	glRotatef(-90.0, 1.0, 0.0, 0.0);
	glScalef(FOOT_WIDTH, 1.0, 1.0);
	gluCylinder(rightAnkle, FOOT_RADIUS, FOOT_RADIUS, FOOT_LENGTH, 10, 10);
	gluDisk(feetCaps, 0.0, FOOT_RADIUS, 10, 10);
	glTranslatef(0.0, 0.0, FOOT_LENGTH);
	gluDisk(feetCaps, 0.0, FOOT_RADIUS, 10, 10);
	glPopMatrix();
}

// Draws the body parts saving and loading the positions through glPop/PushMatrix().
// Uses translations and rotations to move about and draw each quadric.
void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	glRotatef(theta[0], 0.0, 1.0, 0.0);
	glRotatef(theta[1], 1.0, 0.0, 0.0);
	glRotatef(-theta[2], 0.0, 0.0, 1.0);
	torso();
	glPushMatrix();

	glTranslatef(0.0, TORSO_LENGTH+0.5*HEAD_LENGTH, 0.0);
	glRotatef(theta[3], 1.0, 0.0, 0.0);
	glRotatef(theta[4], 0.0, 1.0, 0.0);
	glRotatef(-theta[5], 0.0, 0.0, 1.0);
	head();

	glPopMatrix();
	glPushMatrix();
	glTranslatef(-((TORSO_RADIUS+TORSO_WIDTH/8)+BICEP_RADIUS), 0.9*TORSO_LENGTH, 0.0);
	glRotatef(theta[6], 1.0, 0.0, 0.0);
	glRotatef(theta[7], 0.0, 1.0, 0.0);
	glRotatef(theta[8], 0.0, 0.0, 1.0);
	leftBicep();

	glTranslatef(0.0, BICEP_LENGTH, 0.0);
	glRotatef(theta[9], 1.0, 0.0, 0.0);
	leftForearm();

	glTranslatef(0.0, BICEP_LENGTH, 0.0);
	glRotatef(theta[10], 1.0, 0.0, 0.0);
	leftHand();

	glPopMatrix();
	glPushMatrix();
	glTranslatef((TORSO_RADIUS+TORSO_WIDTH/8)+BICEP_RADIUS, 0.9*TORSO_LENGTH, 0.0);
	glRotatef(theta[11], 1.0, 0.0, 0.0);
	glRotatef(theta[12], 0.0, 1.0, 0.0);
	glRotatef(theta[13], 0.0, 0.0, 1.0);
	rightBicep();

	glTranslatef(0.0, BICEP_LENGTH, 0.0);
	glRotatef(theta[14], 1.0, 0.0, 0.0);
	rightForearm();

	glTranslatef(0.0, BICEP_LENGTH, 0.0);
	glRotatef(theta[15], 1.0, 0.0, 0.0);
	rightHand();

	glPopMatrix();
	glPushMatrix();
	glTranslatef(-(TORSO_RADIUS), 0.1*THIGH_LENGTH, 0.0);
	glRotatef(theta[16], 1.0, 0.0, 0.0);
	glRotatef(theta[17], 0.0, 0.0, 1.0);
	leftThigh();

	glTranslatef(0.0, THIGH_LENGTH, 0.0);
	glRotatef(theta[18], 1.0, 0.0, 0.0);
	leftShin();

	glTranslatef(0.0, THIGH_LENGTH, 0.0);
	glRotatef(theta[19], 1.0, 0.0, 0.0);
	leftFoot();

	glPopMatrix();
	glPushMatrix();
	glTranslatef(TORSO_RADIUS, 0.1*THIGH_LENGTH, 0.0);
	glRotatef(theta[20], 1.0, 0.0, 0.0);
	glRotatef(theta[21], 0.0, 0.0, 1.0);
	rightThigh();

	glTranslatef(0.0, THIGH_LENGTH, 0.0);
	glRotatef(theta[22], 1.0, 0.0, 0.0);
	rightShin();

	glTranslatef(0.0, THIGH_LENGTH, 0.0);
	glRotatef(theta[23], 1.0, 0.0, 0.0);
	rightFoot();

	glPopMatrix();
	glFlush();
	glutSwapBuffers();
}

// Allows movement of C3P0 depending on part selected.
// Toggle wireframe (w) and solid (s) with keys.
void keyboard(unsigned char key, int x, int y)
{
	switch (key)
	{
	case 'd':
		theta[angle] += 4.0;
		if( theta[angle] > 360.0 ) theta[angle] -= 360.0;
		glutPostRedisplay();
		break;
	case 'a':
		theta[angle] -= 4.0;
		if( theta[angle] < -360.0 ) theta[angle] += 360.0;
		glutPostRedisplay();
		break;
	case 'w':
		gluQuadricDrawStyle(rHead, GLU_LINE);
		gluQuadricDrawStyle(eyes, GLU_LINE);
		gluQuadricDrawStyle(rTorso, GLU_LINE);
		gluQuadricDrawStyle(leftShoulder, GLU_LINE);
		gluQuadricDrawStyle(leftElbow, GLU_LINE);
		gluQuadricDrawStyle(leftWrist, GLU_LINE);
		gluQuadricDrawStyle(rightShoulder, GLU_LINE);
		gluQuadricDrawStyle(rightElbow, GLU_LINE);
		gluQuadricDrawStyle(rightWrist, GLU_LINE);
		gluQuadricDrawStyle(leftHip, GLU_LINE);
		gluQuadricDrawStyle(leftKnee, GLU_LINE);
		gluQuadricDrawStyle(leftAnkle, GLU_LINE);
		gluQuadricDrawStyle(rightHip, GLU_LINE);
		gluQuadricDrawStyle(rightKnee, GLU_LINE);
		gluQuadricDrawStyle(rightAnkle, GLU_LINE);
		gluQuadricDrawStyle(tCaps, GLU_LINE);
		gluQuadricDrawStyle(upArmCaps, GLU_LINE);
		gluQuadricDrawStyle(lowArmCaps, GLU_LINE);
		gluQuadricDrawStyle(wristCaps, GLU_LINE);
		gluQuadricDrawStyle(upLegCaps, GLU_LINE);
		gluQuadricDrawStyle(lowLegCaps, GLU_LINE);
		gluQuadricDrawStyle(feetCaps, GLU_LINE);
		glutPostRedisplay();
		break;
	case 's':
		gluQuadricDrawStyle(rHead, GLU_FILL);
		gluQuadricDrawStyle(eyes, GLU_FILL);
		gluQuadricDrawStyle(rTorso, GLU_FILL);
		gluQuadricDrawStyle(leftShoulder, GLU_FILL);
		gluQuadricDrawStyle(leftElbow, GLU_FILL);
		gluQuadricDrawStyle(leftWrist, GLU_FILL);
		gluQuadricDrawStyle(rightShoulder, GLU_FILL);
		gluQuadricDrawStyle(rightElbow, GLU_FILL);
		gluQuadricDrawStyle(rightWrist, GLU_FILL);
		gluQuadricDrawStyle(leftHip, GLU_FILL);
		gluQuadricDrawStyle(leftKnee, GLU_FILL);
		gluQuadricDrawStyle(leftAnkle, GLU_FILL);
		gluQuadricDrawStyle(rightHip, GLU_FILL);
		gluQuadricDrawStyle(rightKnee, GLU_FILL);
		gluQuadricDrawStyle(rightAnkle, GLU_FILL);
		gluQuadricDrawStyle(tCaps, GLU_FILL);
		gluQuadricDrawStyle(upArmCaps, GLU_FILL);
		gluQuadricDrawStyle(lowArmCaps, GLU_FILL);
		gluQuadricDrawStyle(wristCaps, GLU_FILL);
		gluQuadricDrawStyle(upLegCaps, GLU_FILL);
		gluQuadricDrawStyle(lowLegCaps, GLU_FILL);
		gluQuadricDrawStyle(feetCaps, GLU_FILL);
		glutPostRedisplay();
		break;
	default:
		break;
	}
}


// This is our basic 3D point/vector class
struct CVector3
{
public:
    
    // A default constructor
    CVector3() {}

    // This is our constructor that allows us to initialize our data upon creating an instance
    CVector3(float X, float Y, float Z) 
    { 
        x = X; y = Y; z = Z;
    }

    // Here we overload the + operator so we can add vectors together 
    CVector3 operator+(CVector3 vVector)
    {
        // Return the added vectors result.
        return CVector3(vVector.x + x, vVector.y + y, vVector.z + z);
    }

    // Here we overload the - operator so we can subtract vectors 
    CVector3 operator-(CVector3 vVector)
    {
        // Return the subtracted vectors result
        return CVector3(x - vVector.x, y - vVector.y, z - vVector.z);
    }
    
    // Here we overload the * operator so we can multiply by scalars
    CVector3 operator*(float num)
    {
        // Return the scaled vector
        return CVector3(x * num, y * num, z * num);
    }

    // Here we overload the / operator so we can divide by a scalar
    CVector3 operator/(float num)
    {
        // Return the scale vector
        return CVector3(x / num, y / num, z / num);
    }

    float x, y, z;                       
};

CVector3 GetOGLPos(int x, int y)
{
	GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    GLfloat winX, winY, winZ;
    GLdouble posX, posY, posZ;

	glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
	glGetDoublev(GL_PROJECTION_MATRIX, projection);
	glGetIntegerv(GL_VIEWPORT, viewport);

	winX = (float)x;
    winY = (float)viewport[3] - (float)y;
    glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
 
    gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
 
    return CVector3(posX, posY, posZ);
}

void myMouse( int button, int state, int x, int y)
{

	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
	   if(selectstate == 3)
	{
		theta[3] = -GetOGLPos(x, y).y;
		theta[4] = GetOGLPos(x, y).x;
	}
	if(selectstate == 0 || selectstate == 5 || selectstate == 7 || selectstate == 12)  theta[angle] = x;
	else if (selectstate != 0 && selectstate != 3 && selectstate != 5 && selectstate != 7 && selectstate != 12) theta[angle] = y;	
	glutPostRedisplay();
		
	}

}


void motion(int x, int y)
{
	if(selectstate == 3)
	{
		theta[3] = -GetOGLPos(x, y).y;
		theta[4] = GetOGLPos(x, y).x;
	}
	if(selectstate == 0 || selectstate == 5 || selectstate == 7 || selectstate == 12)  theta[angle] = x;
	else if (selectstate != 0 && selectstate != 3 && selectstate != 5 && selectstate != 7 && selectstate != 12) theta[angle] = y;	
	glutPostRedisplay();
}

void myReshape(int w, int h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	if (w <= h)
		glOrtho(-10.0, 10.0, -10.0 * (GLfloat) h / (GLfloat) w, 10.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0);
	else
		glOrtho(-10.0 * (GLfloat) w / (GLfloat) h, 10.0 * (GLfloat) w / (GLfloat) h, 0.0, 10.0, -10.0, 10.0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}


void myinit()
{
	GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
	GLfloat mat_diffuse[] = {1.0, 1.0, 1.0, 1.0};
	GLfloat mat_ambient[] = {1.0, 1.0, 1.0, 1.0};
	GLfloat mat_shininess = {100.0};
	GLfloat light_ambient[] = {0.0, 0.0, 0.0, 1.0};
	//GLfloat light_ambient[] = {0.0, 1.0, 0.0, 0.0}; //Just playing with different lighting here.
	GLfloat light_diffuse[] = {0.858824, 0.858824, 0.439216, 1.0};
	GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
	GLfloat light_position[] = {10.0, 10.0, 10.0, 0.0};
	
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
	glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
	glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);

	glShadeModel(GL_SMOOTH);
	//glShadeModel(GL_FLAT);  // Fun to see differences in flat and smooth shading.
	glEnable(GL_LIGHTING); 
	glEnable(GL_LIGHT0);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_NORMALIZE);
	glEnable(GL_COLOR_MATERIAL);

	glClearColor(1.0, 1.0, 1.0, 1.0);
	glColor3f(0.858824, 0.858824, 0.439216);

	rHead = gluNewQuadric();
	gluQuadricDrawStyle(rHead, GLU_FILL);
	gluQuadricOrientation(rHead, GLU_OUTSIDE);

	eyes = gluNewQuadric();
	gluQuadricDrawStyle(eyes, GLU_FILL);
	gluQuadricOrientation(eyes, GLU_OUTSIDE);

	rTorso = gluNewQuadric();
	gluQuadricDrawStyle(rTorso, GLU_FILL);
	gluQuadricOrientation(rTorso, GLU_OUTSIDE);

	tCaps = gluNewQuadric();
	gluQuadricDrawStyle(tCaps, GLU_FILL);
	gluQuadricOrientation(tCaps, GLU_OUTSIDE);

	upArmCaps = gluNewQuadric();
	gluQuadricDrawStyle(upArmCaps, GLU_FILL);
	gluQuadricOrientation(upArmCaps, GLU_OUTSIDE);

	lowArmCaps = gluNewQuadric();
	gluQuadricDrawStyle(lowArmCaps, GLU_FILL);
	gluQuadricOrientation(lowArmCaps, GLU_OUTSIDE);

	wristCaps = gluNewQuadric();
	gluQuadricDrawStyle(wristCaps, GLU_FILL);
	gluQuadricOrientation(wristCaps, GLU_OUTSIDE);

	upLegCaps = gluNewQuadric();
	gluQuadricDrawStyle(upLegCaps, GLU_FILL);
	gluQuadricOrientation(upLegCaps, GLU_OUTSIDE);

	lowLegCaps = gluNewQuadric();
	gluQuadricDrawStyle(lowLegCaps, GLU_FILL);
	gluQuadricOrientation(lowLegCaps, GLU_OUTSIDE);

	feetCaps = gluNewQuadric();
	gluQuadricDrawStyle(feetCaps, GLU_FILL);
	gluQuadricOrientation(feetCaps, GLU_OUTSIDE);

	leftShoulder = gluNewQuadric();
	gluQuadricDrawStyle(leftShoulder, GLU_FILL);
	gluQuadricOrientation(leftShoulder, GLU_OUTSIDE);

	leftElbow = gluNewQuadric();
	gluQuadricDrawStyle(leftElbow, GLU_FILL);
	gluQuadricOrientation(leftElbow, GLU_OUTSIDE);

	leftWrist = gluNewQuadric();
	gluQuadricDrawStyle(leftWrist, GLU_FILL);
	gluQuadricOrientation(leftWrist, GLU_OUTSIDE);

	rightShoulder = gluNewQuadric();
	gluQuadricDrawStyle(rightShoulder, GLU_FILL);
	gluQuadricOrientation(rightShoulder, GLU_OUTSIDE);

	rightElbow = gluNewQuadric();
	gluQuadricDrawStyle(rightElbow, GLU_FILL);
	gluQuadricOrientation(rightElbow, GLU_OUTSIDE);

	rightWrist = gluNewQuadric();
	gluQuadricDrawStyle(rightWrist, GLU_FILL);
	gluQuadricOrientation(rightWrist, GLU_OUTSIDE);

	leftHip = gluNewQuadric();
	gluQuadricDrawStyle(leftHip, GLU_FILL);
	gluQuadricOrientation(leftHip, GLU_OUTSIDE);

	leftKnee = gluNewQuadric();
	gluQuadricDrawStyle(leftKnee, GLU_FILL);
	gluQuadricOrientation(leftKnee, GLU_OUTSIDE);

	leftAnkle = gluNewQuadric();
	gluQuadricDrawStyle(leftAnkle, GLU_FILL);
	gluQuadricOrientation(leftAnkle, GLU_OUTSIDE);

	rightHip = gluNewQuadric();
	gluQuadricDrawStyle(rightHip, GLU_FILL);
	gluQuadricOrientation(rightHip, GLU_OUTSIDE);

	rightKnee = gluNewQuadric();
	gluQuadricDrawStyle(rightKnee, GLU_FILL);
	gluQuadricOrientation(rightKnee, GLU_OUTSIDE);

	rightAnkle = gluNewQuadric();
	gluQuadricDrawStyle(rightAnkle, GLU_FILL);
	gluQuadricOrientation(rightAnkle, GLU_OUTSIDE);
}

// Menu to handle selections and quit.
// We might be able to use this for menu?
void menu(int selection)
{
	angle = selection;
	selectstate = selection;
   // if(selection < 24 ) angle = selection;
	//if(selection == 24 ) exit(0);
}

// Main method - load it all up and watch it go!
// Create and establish the menu for selecting body
// parts using glutCreateMenu() - a cool feature.
void main(int argc, char **argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
	glutCreateWindow("C3P0");
	myinit();
	glutKeyboardFunc(keyboard);
	glutMouseFunc(myMouse);
	glutMotionFunc(motion);
	glutReshapeFunc(myReshape);
	glutDisplayFunc(display);
	glutCreateMenu(menu);
	glutAddMenuEntry("Torso Rotate", 0);
	glutAddMenuEntry("Torso Pitch", 1);
	glutAddMenuEntry("Torso Side to Side", 2);
	glutAddMenuEntry("Head Control", 3);
	glutAddMenuEntry("Left Shoulder Pitch", 6);
	glutAddMenuEntry("Left Shoulder Rotate", 7);
	glutAddMenuEntry("Left Shoulder Flap", 8);
	glutAddMenuEntry("Left Elbow", 9);
	glutAddMenuEntry("Left Wrist", 10);
	glutAddMenuEntry("Right Shoulder Pitch", 11);
	glutAddMenuEntry("Right Shoulder Rotate", 12);
	glutAddMenuEntry("Right Shoulder Flap", 13);
	glutAddMenuEntry("Right Elbow", 14);
	glutAddMenuEntry("Right Wrist", 15);
	glutAddMenuEntry("Left Hip Pitch", 16);
	glutAddMenuEntry("Left Hip Flap", 17);
	glutAddMenuEntry("Left Knee", 18);
	glutAddMenuEntry("Left Ankle", 19);
	glutAddMenuEntry("Right Hip Pitch", 20);
	glutAddMenuEntry("Right Hip Flap", 21);
	glutAddMenuEntry("Right Knee", 22);			 
	glutAddMenuEntry("Right Ankle", 23);
	//glutAddMenuEntry("Quit", 24);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
	glutMainLoop();
}